/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */

package com.pig4cloud.pigx.contract.app;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.customize.security.utils.SecurityUtil;
import com.pig4cloud.pigx.common.customize.utils.CommonUtil;
import com.pig4cloud.pigx.common.security.service.PigxUser;
import com.pig4cloud.pigx.contract.dto.ContractHistoryOrderDTO;
import com.pig4cloud.pigx.contract.entity.ContractOrderHistory;
import com.pig4cloud.pigx.contract.enums.ContractOrderEnum;
import com.pig4cloud.pigx.contract.enums.ContractPositionEnum;
import com.pig4cloud.pigx.contract.mongo.entity.ContractSymbolMongo;
import com.pig4cloud.pigx.contract.service.ContractOrderHistoryService;
import com.pig4cloud.pigx.contract.utils.ContractUtils;
import com.pig4cloud.pigx.contract.vo.AppContractCurrentOrderVO;
import com.pig4cloud.pigx.contract.vo.ContractOrderDetailedVO;
import io.seata.common.util.CollectionUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 历史订单表
 *
 * @since 2022-08-11 10:08:11
 */
@RestController
@RequestMapping("/app/order/history")
@Api(value = "appOrderHistory", tags = "app历史订单管理")
@AllArgsConstructor
public class AppContractOrderHistoryController {

	private final ContractOrderHistoryService contractOrderHistoryService;
	private final ContractUtils contractUtils;

	/**
	 * 分页查询
	 *
	 * @param condition 查询条件
	 * @return {@link R< Page< AppContractCurrentOrderVO>>}
	 * @since 2022/9/21 16:58
	 */
	@PostMapping("/page")
	@ApiOperation(value = "分页查询", notes = "分页查询")
	public R<Page<AppContractCurrentOrderVO>> page(@RequestBody ContractHistoryOrderDTO condition) {
		// 获取当前登陆人
		PigxUser user = SecurityUtil.getLoginUserNotNull();
		condition.setUserId(user.getId());

		// 组装查询条件
		Page<ContractOrderHistory> page = new Page<>();
		page.setCurrent(condition.getPageNum());
		page.setSize(condition.getPageSize());
		QueryWrapper<ContractOrderHistory> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda()
				.eq(ContractOrderHistory::getUserId, condition.getUserId())
				.eq(!Objects.isNull(condition.getSymbolId()), ContractOrderHistory::getSymbolId, condition.getSymbolId())
				.in(!CollectionUtils.isEmpty(condition.getStatus()), ContractOrderHistory::getStatus, condition.getStatus())
				.in(!CollectionUtils.isEmpty(condition.getSide()), ContractOrderHistory::getSide, condition.getSide())
				.in(!CollectionUtils.isEmpty(condition.getType()), ContractOrderHistory::getType, condition.getType())
				.gt(!Objects.isNull(condition.getStartTime()), ContractOrderHistory::getCreateTime, condition.getStartTime())
				.lt(!Objects.isNull(condition.getEndTime()), ContractOrderHistory::getCreateTime, condition.getEndTime().minusDays(-1))
				.orderByDesc(true, ContractOrderHistory::getCreateTime);

		// 转换到vo
		List<AppContractCurrentOrderVO> voList = new ArrayList<>();
		Page<ContractOrderHistory> orderPage = contractOrderHistoryService.page(page, queryWrapper);
		List<ContractOrderHistory> orders = orderPage.getRecords();
		for (ContractOrderHistory order : orders) {
			AppContractCurrentOrderVO vo = new AppContractCurrentOrderVO();
			BeanUtils.copyProperties(order, vo);
			vo.setId(order.getId().toString());
			voList.add(vo);
		}

		// 遍历
		voList.forEach(vo -> {
			vo.setCurrencyNum(vo.getNum().multiply(vo.getPrice()));
			if (vo.getDealNum() != null && vo.getDealAvg() != null) {
				vo.setCurrencyDealNum(vo.getDealNum().multiply(vo.getDealAvg()));
			}
			// 翻译字典项
			vo.setType(ContractOrderEnum.Type.findName(vo.getType()));
			vo.setPositionMode(ContractPositionEnum.Mode.findName(vo.getPositionMode()));
			vo.setSide(ContractOrderEnum.Side.findName(vo.getSide()));
			vo.setOperationType(ContractOrderEnum.OperationType.findName(vo.getOperationType()));
			vo.setStatus(ContractOrderEnum.Status.findName(vo.getStatus()));

			// 查询币对
			ContractSymbolMongo symbol = contractUtils.getSymbolFromThread(vo.getSymbolName());

			// 主币外币名称
			vo.setMainCurName(symbol.getMainCurName());
			vo.setTokenCurName(symbol.getTokenCurName());
			vo.setSheet(symbol.getSheet());
			// 设置精度
			contractUtils.setScaleBySymbol(vo, vo.getSymbolName());
		});

		Page<AppContractCurrentOrderVO> voPage = new Page<>();
		BeanUtils.copyProperties(orderPage, voPage);
		voPage.setRecords(voList);

		// 清空localThread币对缓存
		ContractUtils.removeSymbolThreadCache();
		return R.ok(voPage);
	}

	/**
	 * 详情
	 *
	 * @param id 订单id
	 * @return {@link R}
	 * @since 2022/9/21 17:10
	 */
	@ApiOperation(value = "查询详情", notes = "查询详情")
	@GetMapping("/{id}")
	public R<ContractOrderDetailedVO> detail(@PathVariable("id") Long id) {
		ContractOrderDetailedVO detail = contractOrderHistoryService.appDetail(id);
		return R.ok(detail);
	}
}
